<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="zh-CN"><link href="stylesheet.css" media="all" rel="stylesheet" type="text/css">
<title>DECLARE</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head><body class="REFENTRY">
<div>
<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><th colspan="5" align="center" valign="bottom">PostgreSQL 8.2.3 中文文档</th></tr>
<tr><td width="10%" align="left" valign="top"><a href="sql-deallocate.html" accesskey="P">后退</a></td><td width="10%" align="left" valign="top"><a href="sql-deallocate.html">快退</a></td><td width="60%" align="center" valign="bottom"></td><td width="10%" align="right" valign="top"><a href="sql-delete.html">快进</a></td><td width="10%" align="right" valign="top"><a href="sql-delete.html" accesskey="N">前进</a></td></tr>
</table>
<hr align="LEFT" width="100%"></div>
<h1><a name="SQL-DECLARE"></a>DECLARE</h1>
<div class="REFNAMEDIV"><a name="AEN50081"></a><h2>名称</h2>DECLARE&nbsp;--&nbsp;定义一个游标</div>
<a name="AEN50084"></a><a name="AEN50086"></a>
<div class="REFSYNOPSISDIV"><a name="AEN50089"></a><h2>语法</h2>
<pre class="SYNOPSIS">DECLARE <tt class="REPLACEABLE"><i>name</i></tt> [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]
    CURSOR [ { WITH | WITHOUT } HOLD ] FOR <tt class="REPLACEABLE"><i>query</i></tt>
    [ FOR { READ ONLY | UPDATE [ OF <tt class="REPLACEABLE"><i>column</i></tt> [, ...] ] } ]</pre>
</div>
<div class="REFSECT1"><a name="AEN50094"></a><h2>描述</h2>
<p><tt class="COMMAND">DECLARE</tt> 允许用户创建游标，用于在一个大的查询里面检索少数几行数据。使用 <a href="sql-fetch.html"><i>FETCH</i></a> ，游标可以返回文本或二进制格式。</p>
<p>通常游标和 <tt class="COMMAND">SELECT</tt> 一样返回文本格式。因为数据在系统内部是用二进制格式存储的，系统必须对数据做一定转换以生成文本格式。一旦数据是以文本形式返回，那么客户端应用需要把它们转换成二进制进行操作。另外，文本格式一般都比对应的二进制格式占用的存储空间大。二进制游标返回内部二进制形态的数据，可能更易于操作。当然，如果你想以文本方式显示数据，那么以文本方式检索会为你节约很多客户端的工作。</p>
<p>比如，如果查询从某个整数列返回 1 ，在缺省的游标里将获得一个字符串 <tt class="LITERAL">1</tt> ，但在二进制游标里将得到一个 4 字节的包含该数值内部形式的数值(大端顺序)。</p>
<p>应该小心使用二进制游标。一些客户端应用(比如 <span class="APPLICATION">psql</span>)是不能识别二进制游标的，它们期望返回的数据是文本格式。</p>
<div class="NOTE">
<blockquote class="NOTE">
<p><b>【注意】</b>如果客户端应用使用"扩展查询"协议发出 <tt class="COMMAND">FETCH</tt> 命令，那么 Bind 协议声明数据是用文本还是用二进制格式检索。这个选择覆盖游标的定义。因此，在使用扩展查询协议的时候，二进制游标的概念已经过时了，任何游标都可以当作文本或者二进制的格式发出。</p>
</blockquote>
</div>
</div>
<div class="REFSECT1"><a name="AEN50109"></a><h2>参数</h2>
<div class="VARIABLELIST">
<dl>
<dt><tt class="REPLACEABLE"><i>name</i></tt></dt>
<dd><p>将要创建的游标名</p></dd>
<dt><tt class="LITERAL">BINARY</tt></dt>
<dd><p>令游标以二进制而不是文本格式返回数据</p></dd>
<dt><tt class="LITERAL">INSENSITIVE</tt></dt>
<dd><p>表明从游标检索出来的数据不应该被其它进程或游标的更新动作影响。在 PostgreSQL 里，所有游标都是不敏感的，这个关键字没有什么作用，提供它只是为了和 SQL 标准兼容。</p></dd>
<dt><tt class="LITERAL">SCROLL</tt><br><tt class="LITERAL">NO SCROLL</tt></dt>
<dd><p><tt class="LITERAL">SCROLL</tt> 声明该游标可以用于以倒序的方式检索数据行(也就是反向检索)。根据查询的执行计划的不同，声明 <tt class="LITERAL">SCROLL</tt> 可能会对查询的执行时间有不良影响。<tt class="LITERAL">NO SCROLL</tt> 声明该游标不能用于以倒序的方式检索数据行。缺省仅允许在某些情况下倒序检索，这不同于指定 <tt class="LITERAL">SCROLL</tt> 。参见 <a href="sql-declare.html#SQL-DECLARE-NOTES"><i>Notes</i></a> 获取细节。</p></dd>
<dt><tt class="LITERAL">WITH HOLD</tt><br><tt class="LITERAL">WITHOUT HOLD</tt></dt>
<dd><p><tt class="LITERAL">WITH HOLD</tt>(缺省)声明该游标可以在创建它的事务成功提交后继续使用。<tt class="LITERAL">WITHOUT HOLD</tt> 声明该游标不能在创建它的事务提交后使用。</p></dd>
<dt><tt class="REPLACEABLE"><i>query</i></tt></dt>
<dd><p>一个 <a href="sql-select.html"><i>SELECT</i></a> 或 <a href="sql-values.html"><i>VALUES</i></a> 命令，它提供游标返回的行。</p></dd>
<dt><tt class="LITERAL">FOR READ ONLY</tt><br><tt class="LITERAL">FOR UPDATE</tt></dt>
<dd><p><tt class="LITERAL">FOR READ ONLY</tt> 表明游标将用于只读模式。<tt class="LITERAL">FOR UPDATE</tt> 表明游标将被用于更新表。因为目前 PostgreSQL 不支持游标更新，所以声明 <tt class="LITERAL">FOR UPDATE</tt> 将产生一个错误信息。而声明 <tt class="LITERAL">FOR READ ONLY</tt> 没有作用。</p></dd>
<dt><tt class="REPLACEABLE"><i>column</i></tt></dt>
<dd><p>将被更新的列。因为游标更新目前不被 PostgreSQL 支持，所以 <tt class="LITERAL">FOR UPDATE</tt> 子句将产生一个错误信息。</p></dd>
</dl>
</div>
<p><tt class="LITERAL">BINARY</tt>, <tt class="LITERAL">INSENSITIVE</tt>, <tt class="LITERAL">SCROLL</tt> 关键字可以以任何顺序出现。</p>
</div>
<div class="REFSECT1"><a name="SQL-DECLARE-NOTES"></a><h2>注意</h2>
<p>如果没有声明 <tt class="LITERAL">WITH HOLD</tt> ，那么这个命令创建的游标只能在当前事务中使用。这样，不带 <tt class="LITERAL">WITH HOLD</tt> 的 <tt class="COMMAND">DECLARE</tt> 在事务块外面没有任何用处：游标将一直存活到事务结束。因此，PostgreSQL 将在这个命令出现在事务块外面的时候报错。使用 <a href="sql-begin.html"><i>BEGIN</i></a>, <a href="sql-commit.html"><i>COMMIT</i></a> 和 <a href="sql-rollback.html"><i>ROLLBACK</i></a> 定义一个事务块。</p>
<p>如果声明了 <tt class="LITERAL">WITH HOLD</tt> 并且创建该游标的事务成功提交，那么游标还可以在同一会话随后的事务里访问。但如果创建它的事务回滚，那么游标被删除。带 <tt class="LITERAL">WITH HOLD</tt> 创建的游标是用一个明确的 <tt class="COMMAND">CLOSE</tt> 命令或者是会话终止来关闭的。在目前的实现里，由一个游标代表的行是被拷贝到一个临时文件或者内存区里的，这样他们就仍然可以在随后的事务中被访问。</p>
<p>在定义一个要用来反向抓取的游标的时候，应该声明 <tt class="LITERAL">SCROLL</tt> 选项，这是 SQL 标准要求的。不过，为了和早期的版本兼容，只要游标的查询计划简单得不需要额外的开销，PostgreSQL 在没有声明 <tt class="LITERAL">SCROLL</tt> 的时候也允许反向抓取。不过，建议应用开发人员不要依赖于使用没有使用 <tt class="LITERAL">SCROLL</tt> 定义的游标的反向查找功能。如果声明了 <tt class="LITERAL">NO SCROLL</tt> ，那么不管怎样都会禁止反向抓取的功能。</p>
<p>SQL 标准中的游标只能在嵌入SQL(ESQL)的应用中使用。PostgreSQL 服务器没有一个明确的 <tt class="COMMAND">OPEN</tt> 语句；一个游标被认为在定义时就已经打开了。不过，PostgreSQL 嵌入的 SQL 预编译器(<span class="APPLICATION">ECPG</span>)支持 SQL 标准的习惯，包括那些和 <tt class="COMMAND">DECLARE</tt> 和 <tt class="COMMAND">OPEN</tt> 相关的语句。</p>
<p>可以通过查询 <a href="view-pg-cursors.html"><tt class="STRUCTNAME">pg_cursors</tt></a> 系统视图看到所有可用游标。</p>
</div>
<div class="REFSECT1"><a name="AEN50213"></a><h2>例子</h2>
<p>定义一个游标：</p>
<pre class="PROGRAMLISTING">DECLARE liahona CURSOR FOR SELECT * FROM films;</pre>
<p>参阅 <a href="sql-fetch.html"><i>FETCH</i></a> 获取有关游标使用的更多例子。</p>
</div>
<div class="REFSECT1"><a name="AEN50218"></a><h2>兼容性</h2>
<p>SQL 标准只允许在嵌入的 SQL 中和模块中使用游标。PostgreSQL 允许交互地使用游标。</p>
<p>SQL 标准允许游标更新表数据。所有 PostgreSQL 的游标都是只读的。</p>
<p>二进制游标是 PostgreSQL 扩展。</p>
</div>
<div class="REFSECT1"><a name="AEN50227"></a><h2>又见</h2><a href="sql-close.html"><i>CLOSE</i></a>, <a href="sql-fetch.html"><i>FETCH</i></a>, <a href="sql-move.html"><i>MOVE</i></a></div>
<div>
<hr align="LEFT" width="100%">
<table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td width="33%" align="left" valign="top"><a href="sql-deallocate.html" accesskey="P">后退</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">首页</a></td><td width="33%" align="right" valign="top"><a href="sql-delete.html" accesskey="N">前进</a></td></tr>
<tr><td width="33%" align="left" valign="top">DEALLOCATE</td><td width="34%" align="center" valign="top"><a href="sql-commands.html" accesskey="U">上一级</a></td><td width="33%" align="right" valign="top">DELETE</td></tr>
</table>
</div>
</body></html>